/*
 * Terrier - Terabyte Retriever
 * Webpage: http://ir.dcs.gla.ac.uk/terrier
 * Contact: terrier{a.}dcs.gla.ac.uk
 * University of Glasgow - Department of Computing Science
 * http://www.gla.ac.uk/
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is SearchRequest.java.
 *
 * The Original Code is Copyright (C) 2004-2009 the University of Glasgow.
 * All Rights Reserved.
 *
 * Contributor(s):
  *   Craig Macdonald <craigm{a.}dcs.gla.ac.uk> (original author)
 */
package uk.ac.gla.terrier.querying;
import java.io.Serializable;
import uk.ac.gla.terrier.matching.ResultSet;
import uk.ac.gla.terrier.querying.parser.Query;
/** SearchRequest is the one of two main classes of which are made available to client code by
  * the Terrier framework at retrieval time. Each search query, whether entered by a user or
  * in batch mode retrieval creates a search request. Each search request is then passed to 4
  * methods of the Manager that is handling each search request: runPreProcessing, runMatching,
  * runPostProcess and runPostFilters
  * Example usage:
  * <pre>
  * Index index = new Index()
  * Manager manager = new Manager(index);
  * SearchRequest srq = manager.newSearchRequest();
  * //parse the query
  * TerrierLexer lexer = new TerrierLexer(new StringReader(query));
  * TerrierFloatLexer flexer = new TerrierFloatLexer(lexer.getInputState());

  * TokenStreamSelector selector = new TokenStreamSelector();
  * selector.addInputStream(lexer, "main");
  * selector.addInputStream(flexer, "numbers");
  * selector.select("main");
  * TerrierQueryParser parser = new TerrierQueryParser(selector);
  * parser.setSelector(selector);
  *
  * srq.setQuery(parser.query());
  * srq.setQuery(query);
  * //run the query
  * m.runPreProcessing(srq);
  * manager.runMatching(srq);
  * manager.runPostProcess(srq);
  * manager.runPostFilters(srq);
  * </pre>
  * <P><B>NB:</B>Controls (name, value tuples ) are used to control the retrieval prcoess. You may 
  * want to set controls in your application code. However, default controls can be set using 
  * the <tt>querying.default.controls</tt> property in the terrier.properties file.
  */
public interface SearchRequest extends Serializable
{
	/** Set the matching model and weighting model that the Manager should use for this query.
	  * The Matching model  should be a subclass of uk.ac.gla.terrier.matching.Matching, and
	  * the weighting model should implement uk.ac.gla.terrier.matching.Model.<br>
	  * Example: <tt>request.addMatchingModel("Matching", "PL2")</tt>
	  * @param MatchingModelName the String class name that should be used
	  * @param WeightingModelName the String class name that should be used */
	public void addMatchingModel(String MatchingModelName, String WeightingModelName);
	/** Set the query to be a parsed Query syntax tree, as generated by the Terrier query parser
	  * @param q The Query object syntax tree */
	public void setQuery(Query q);
	/** Set a unique identifier for this query request.
	  * @param qid the unique string identifier*/
	public void setQueryID(String qid);
	/** Get the Query syntax tree
	  * @return The query object as set with setQuery.
	  * */
	public Query getQuery();
	/** Set a control named to have value Value. This is essentially a
	  * hashtable wrappers. Controls are used to set properties of the
	  * retrieval process.
	  * @param Name the name of the control to set the value of.
	  * @param Value the value that the control should take. */
	public void setControl(String Name, String Value);
	/** Returns the query id as set by setQueryID(String).
	  * @return the query Id as a string. */
	public String getQueryID();
	/** Returns the resultset generated by the query. Before retrieving this
	  * you probably need to have run Manager.runMatching, and (optionally, at
	  * your own risk) Manager.runPostProcesses() and Manager.runPostFiltering().
	  * @return ResultSet the resultset - ie the set of document Ids and their scores. */
	public ResultSet getResultSet();
	/** Returns the value of the control. Null or empty string if not set.
	  * @return the value. */
	public String getControl(String Name);
	/** Set if the query input had no terms.
	  * @return true if the query has no terms. Used by Manager.runMatching() to short circuit the
	  * matching process - if this is set, then a resultset with 0 documents is created
	  * automatically.
	  * @return true if the query has no terms */
	public boolean isEmpty();

	/**
	 * sets the original query, before any preprocessing
	 */
	public void setOriginalQuery(String q);
	
	/**
	 * gets the original query, before any preprocessing
	 */
	public String getOriginalQuery();
	
	/**
	 * Sets the number of documents returned for a search request, after
	 * applying post filtering
	 * @param n
	 */
	public void setNumberOfDocumentsAfterFiltering(int n);
	
	/**
	 * gets the number of documents returned for a search request, after
	 * applying post filtering
	 * @return the number of documents returned for a search request. integer.
	 */
	public int getNumberOfDocumentsAfterFiltering();
	
	public long getStartedProcessingTime();
	
	public void setStartedProcessingTime(long time);
	
}
/* the following methods are implmented in the SearchRequest - ie Request.java
   so are only visible from inside the querying package:
        public String getWeightingModel()
        public String getMatchingModel()
        public void setControl(String Name, String Value)
        public void setResultSet(ResultSet results)
        public ResultSet getResultSet()
        public String getControl(String Name)
        public Hashtable getControlHashtable()
        public boolean isEmpty()
        public void setEmpty(boolean in)
        public void setMatchingQueryTerms(MatchingQueryTerms mqts)
        public MatchingQueryTerms getMatchingQueryTerms()
*/
